package com.xuanyue.db.xuan.core.index;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import com.xuanyue.db.xuan.core.exception.IndexException;
import com.xuanyue.db.xuan.core.exception.SQLException;
import com.xuanyue.db.xuan.core.table.IBitIndex;
import com.xuanyue.db.xuan.core.table.IColumn;
import com.xuanyue.db.xuan.core.table.INumberColumn;
import com.xuanyue.db.xuan.core.table.ISortElement;
import com.xuanyue.db.xuan.core.table.expr.Expr;
import com.xuanyue.db.xuan.core.table.expr.ExprValue;
import com.xuanyue.db.xuan.core.table.expr.ExprValueType;
import com.xuanyue.db.xuan.core.table.expr.SortTemplate;
import com.xuanyue.db.xuan.msg.VLAUETYPE;
/**
 * 最小精度为秒
 * 用制定的长度存放。
 * size：表示字段长度
 * [1970-01-01 00:00:00]减 2^size+1秒    到  [1970-01-01 00:00:00]加 2^size-+1秒   之间的时间数据。
 * 默认用34位有符号整形存放，     即可以正确处理               [1970-01-01 00:00:00]减 2^24+1秒    到  [1970-01-01 00:00:00]加 2^24-+1秒   之间的时间数据。
 * （大约是1970年上下浮动544年          [1426,2514] ）
 * @author 解观海
 * @email  guanhaixie@sina.cn
 * @date 2020年6月23日
 * @version 0.1
 */
public class DateIndex implements INumberColumn<Date>{
	
	private NumberIndex data = new NumberIndex(35);
	private String path;
	
	public NumberIndex getData() {
		return data;
	}

	@Override
	public boolean modify(IColumn newOne,boolean cpDataFromOld) {
		return false;
	}
	
	@Override
	public void setPath(String path) {
		this.path = path;
		data.setPath(String.format("%s/data", path));
	}
	public DateIndex() {
		this(35);
	}
	public DateIndex(int size) {
		data = new NumberIndex(size);
	}
	public IBitIndex getMask() {
		return data.getMask();
	}
	@Override
	public void flush(int maxId) {
		data.flush(maxId);
	}
	@Override
	public void equeals(IBitIndex cache, Number valueO) {
		if(valueO==null) {
			cache.copyFrom(getMask());
			cache.not();
			return;
		}
		data.equeals(cache, valueO);
	}

	@Override
	public void greater(IBitIndex cache, IBitIndex now, Number valueO) {
		data.greater(cache, now, valueO);
	}

	@Override
	public void less(IBitIndex cache, IBitIndex now,Number valueO) {
		data.less(cache, now, valueO);
	}

	@Override
	public void greaterAndEq(IBitIndex cache, IBitIndex now, Number valueO) {
		data.greaterAndEq(cache, now, valueO);
	}

	@Override
	public void lessAndEq(IBitIndex cache, IBitIndex now, Number valueO) {
		data.lessAndEq(cache, now, valueO);
	}

	@Override
	public void set(int rowId, ExprValue valueO) {
		if(ExprValueType.DATE.is(valueO.getType())) {
			Date value=valueO.getValue();
			ExprValue v = new ExprValue();
			v.setType(ExprValueType.LONG);
			v.setValue(value.getTime()/1000 );
			data.set(rowId, v);
		}else if(ExprValueType.NULL.is(valueO.getType())) {
			data.set(rowId, valueO);
		}else {
			throw new SQLException("value type ERROR:"+valueO.getType()+"  is not a Date value");
		}
			
		
	}

	@Override
	public Date get(int rowId) {
		Long ms = data.get(rowId);
		if(ms==null) {
			return null;
		}
		return new Date(ms*1000);
	}

	@Override
	public ExprValue getExprValue(int rowId) {
		return new ExprValue(ExprValueType.DATE, get(rowId));
	}
	
	@Override
	public void save() {
		File p = new File(path);
		if(!p.exists()) {
			p.mkdirs();
		}
		data.save();
	}

	@Override
	public void load()  {
		File p = new File(path);
		if(!p.exists()) {
			throw new IndexException(String.format("%s is not exists", path));
		}
		data.load();
	}
	@Override
	public void init() {
		File p = new File(path);
		if(!p.exists()) {
			p.mkdirs();
		}
		data.init();
	}
	@Override
	public int getDataSize() {
		return data.getDataSize();
	}
	public static void main(String[] args) throws ParseException {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		Date d = new Date();
		System.out.println(formatter.format(d));
		System.out.println(formatter.parse("1970-01-01 08:00:00").getTime());
		
		System.out.println(d.getTime()/1000);
	}
	@Override
	public List<ISortElement> getSortE(SortTemplate sortTemplate) {
		return data.getSortE(sortTemplate);
	}
	@Override
	public VLAUETYPE getType() {
		return VLAUETYPE.DATE;
	}
	@Override
	public void saveRow( int rowId){
		data.saveRow( rowId);
	}
	@Override
	public boolean checkSortE(SortTemplate sortTemplate) {
		return sortTemplate.isType(SortTemplate.GENERAL);
	}
	@Override
	public boolean checkType(ExprValue v) {
		return ExprValueType.DATE.is(v.getType())||ExprValueType.NULL.is(v.getType());
	}
	@Override
	public void exe(Expr expr, List<IBitIndex> caches) {
		ExprValue value = expr.getValue();
		ExprValue ev = new ExprValue();
		if(ExprValueType.DATE.is(expr.getValue().getType())){
			Date tar = value.getValue();
			ev.setType(ExprValueType.LONG);
			ev.setValue( tar.getTime()/1000);
		}else if(ExprValueType.NULL.is(expr.getValue().getType())){
			ev.setType(value.getType());
		}else {
			throw new SQLException("the expr value type is not supoort :"+ value.getType());
		}
		Expr in = new Expr();
		in.setValue(ev);
		in.setOp(expr.getOp());
		data.exe(in, caches);
	}
	@Override
	public int checkAndContSource(Expr expr) {
		ExprValue value = expr.getValue();
		Expr in = new Expr();
		ExprValue ev = new ExprValue();
		if(ExprValueType.DATE.is(expr.getValue().getType())){
			Date tar = value.getValue();
			ev.setType(ExprValueType.LONG);
			ev.setValue( tar.getTime()/1000);
		}else if(ExprValueType.NULL.is(expr.getValue().getType())){
			ev.setType(value.getType());
		}else {
			return 0;
		}
		
		in.setValue(ev);
		in.setOp(expr.getOp());
		return data.checkAndContSource(in);
		
	}
}
